import cv2 as cv
import numpy as np
from scipy.interpolate import CubicSpline
import matplotlib.pyplot as plt
import time

#更改方案：
#1：将一张图改成两张图
#2:将三个点改成，选择第一个点，牙尖，第二个点，深度，第三个点，直线
#3：计算距离，然后打分


#一些全局参数
p_window_X = 100#窗口横坐标
p_window_Y = 100#窗口纵坐标
s_windows_X =600 #窗口宽度
s_windows_Y =400 #窗口高度
class ImageAnnotator:
    def __init__(self):
        self.ind = 0
        self.points = []
        #self.dic = {
        #    '1': "Buccal groove of the second permanent molar",
        #    '2': "Second premolar buccal cusp",
        #    '3': "Anterior incisor cusp"
        #}
        self.dic = {
            '1':"complete the Anetrior incisor cusp",
            '2':"second premolar buccal cusp",
            '3':"calculate the spee with the line"
        }
        self.rate_X = None# 统一标准的比例
        self.rate_Y = None# 统一标准的比例

        self.img = cv.imread("image_5.jpg")

        self.img2 = cv.imread("image_5.jpg")
        self.CalculateRatio()
        cv.namedWindow('image',cv.WINDOW_NORMAL)
        cv.setWindowProperty('image', cv.WND_PROP_FULLSCREEN, cv.WINDOW_FULLSCREEN)
        cv.resizeWindow('image', s_windows_X, s_windows_Y)
        cv.moveWindow('image', p_window_X, p_window_Y)

        cv.setMouseCallback('image', self.draw_circle)

    def CalculateRatio(self):
        height, width, channels = self.img.shape
        #print(height)
        self.rate_X = 640/width  # 统一标准的比例
        self.rate_Y = 480/height  # 统一标准的比例
        #print(self.rate_X)


    def draw_circle(self, event, x, y, flags, param):
        if event == cv.EVENT_LBUTTONDOWN:
            self.ind += 1
            cv.circle(self.img, (x, y), 4, (255, 0, 200), -1)
            if self.ind ==1 :
                font = cv.FONT_HERSHEY_SIMPLEX
                cv.putText(self.img, self.dic.get(str(self.ind), "Unknown"), (x-60, y-40), font, 0.5, (255, 255, 255), 2, cv.LINE_AA)
            elif self.ind ==2:
                font = cv.FONT_HERSHEY_SIMPLEX
                cv.putText(self.img,self.dic.get(str(self.ind), "Unknown"), (x, y+60), font, 0.5, (255, 255, 255), 2, cv.LINE_AA)
                content = f'please choose the position of your back tooth'
                cv.putText(self.img, content, (260, 60), font, 0.5, (255, 255, 255),
                           2, cv.LINE_AA)
            else:

                font = cv.FONT_HERSHEY_SIMPLEX
                cv.putText(self.img, self.dic.get(str(self.ind), "Unknown"), (x+60, y+40), font, 0.5, (255, 255, 255), 2, cv.LINE_AA)
                cv.line(self.img,(x,y),(self.points[0][0],self.points[0][1]),(162,205,62),1,1)

            self.points.append((x, y))
            if len(self.points) == 3:
                self.draw_fitted_curve()

    def draw_fitted_curve(self):
        if len(self.points)<=2:
            return
        #start_time = time.time()
        points_np = np.array(self.points)#将三个点转换为numpy格式
        x = points_np[:, 0]#分别获得x，y的值
        y = points_np[:, 1]


        #对x进行从大到小的排序
        for ind1 in range(0,len(x)):

            for ind2 in range(0,len(x)):
                if x[ind2] >= x[ind1]:
                    temp1 =x[ind1]
                    temp2 =y[ind1]
                    x[ind1] =x[ind2]
                    y[ind1] = y[ind2]
                    x[ind2] =temp1
                    y[ind2] =temp2
                else : pass
        #print("########",x)
        # 计算 x 的扩展范围
        x_min = min(x) - 50  # 向左扩展 50 像素
        x_max = max(x) + 50  # 向右扩展 50 像素

        # 使用 CubicSpline 进行拟合
        cs = CubicSpline(x, y, bc_type='natural')
        curvature = []
        x_new = np.linspace(x_min, x_max, 500)
        y_new = cs(x_new)
        #计算高度像素值：

        D = self.calculate()
        print(D)
        DD = 110-D
        if D<=20:
            score =100
        elif D>=110:
            score =0
        else:
            score = -0.0161*DD**2+2.4799*DD+3.4034

        for i in range(len(x_new) - 1):
            cv.line(self.img, (int(x_new[i]), int(y_new[i])), (int(x_new[i + 1]), int(y_new[i + 1])), (162,205,62), 2)

        print("您的spee咬合曲线得分为：",score)
        print(self.img.shape)
        content = f'Spee score:{score}'
        font = cv.FONT_HERSHEY_SIMPLEX
        cv.putText(self.img, content, (60, 60), font, 0.5, (255, 255, 255),
                   2, cv.LINE_AA)
    def calculate(self):

        x1 = self.points[0][0]*self.rate_X
        y1 = self.points[0][1]*self.rate_Y
        x2 = self.points[2][0]*self.rate_X
        y2 = self.points[2][1]*self.rate_Y
        x0 = self.points[1][1]*self.rate_X
        y0 = self.points[1][1]*self.rate_Y
        #自己推的点到直线距离公式
        up =np.abs((x2-x1)*y0 + (y1-y2)*x0 + x1*y2-x2*y1)
        down =np.sqrt((x2-x1)**2+(y1-y2)**2)
        D =up/down
        return D

    def run(self):
        while True:
            cv.imshow('image', self.img)
            if cv.waitKey(20) & 0xFF == 27:  # 按 'Esc' 键退出
                break

        cv.destroyAllWindows()

if __name__ == "__main__":
    annotator = ImageAnnotator()
    annotator.run()
